package
{
	import flash.display.DisplayObject;
	import flash.display.Graphics;
	import flash.display.Shader;
	import flash.display.Shape;
	import flash.display.SimpleButton;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.events.TimerEvent;
	import flash.geom.Rectangle;
	import flash.net.URLVariables;
	import flash.text.TextField;
	import flash.net.URLLoader;
	import flash.net.URLRequest;
	import flash.net.URLRequestMethod;
	import flash.net.URLLoaderDataFormat;
	import flash.text.TextFormat;
	import flash.utils.Timer;
	//import com.demonsters.debugger.MonsterDebugger;
	
	/**
	 * ...
	 * @author ivan
	 */
	public class Main extends Sprite
	{
		private var BATTLE_ID:int;
		private var PLAYER_COLOR:int;
		private var MAX_X:int;
		private var MAX_Y:int;
		
		private var HEIGHT:int = 600;
		private var WIDTH:int = 900;
		private var PANEL_WIDTH:int = 120;
		private var COLOR1:int = 0xB00000;
		private var COLOR2:int = 0x0000B0;
		private var BG_COLOR:int = 0xC4F0E4;
		private var BG_PANEL:int = 0xAA9084;
		private var NET_COLOR:int = 0x000000;
		
		private var timer:Timer;
		private var spr:Sprite = new Sprite();
		private var panel:Sprite = new Sprite();
		
		private var dots:Array;
		private var current_player:int;
		private var winner:int = 0;
		
		private var nx:int;
		private var ny:int;
		
		private var autor_login:String;
		private var guest_login:String;
		
		private var tf_login_active:TextFormat;
		private var tf_login_passive:TextFormat;
		//var tf_header:TextFormat;
		private var tf_info:TextFormat;
		private var tf_chat:TextFormat;
		
		private var tx_login1:TextField;
		private var tx_login2:TextField;
		private var tx_dots1:TextField;
		private var tx_dots2:TextField;
		private var tx_chat:TextField;
		private var tx_message:TextField;
		private var submit_message:SimpleButton;
		private var loose:SimpleButton;
		private var s1:Sprite;
		private var s2:Sprite;
		
		
		private function get d():Number
		{
			return WIDTH / (MAX_X);
		}
		
		private function get h():Number
		{
			return WIDTH / (MAX_X) / 2;
		}
		
		private function get max_area():int
		{
				return MAX_X * MAX_Y / 5;
		}
		
		private function get win_area():int
		{
			return MAX_X * MAX_Y * 0.4;
		}
		
		private function get dot_rad():int
		{
			return d / 7 + 2;
		}
		
		private function get net_style():int
		{
			return d / 30 + 1;
		}
		
		private function get E():int
		{
			return d / 3 + 1;
		}
		
		private function getSq(col:int):int
		{
			var num:int = 0;
			for (var i:int = 0; i < MAX_X; i++)
				for (var j:int = 0; j < MAX_Y; j++)
					if (dots[i][j] == col || dots[i][j] == col+2 || dots[i][j] == col+4)
						num++;
			return num;
		}
		
		public function Main():void
		{
			if (stage)
				init();
			else
				addEventListener(Event.ADDED_TO_STAGE, init);
		}
		
		private function init(e:Event = null):void
		{
			removeEventListener(Event.ADDED_TO_STAGE, init);
			//MonsterDebugger.initialize(this);
			//MonsterDebugger.trace(this, "Hello here!");
			
			var loadvars:URLLoader = new URLLoader();
			loadvars.dataFormat = URLLoaderDataFormat.VARIABLES;
			loadvars.addEventListener(Event.COMPLETE, load);
			try
			{
				loadvars.load(new URLRequest("scripts/load.php"));
			}
			catch (error:Error)
			{
				trace('error in init');
			}
		}
		
		private function load(e:Event = null):void
		{
			var loader:URLLoader = URLLoader(e.target);
			BATTLE_ID = loader.data.battleID;
			PLAYER_COLOR = loader.data.player_color;
			current_player = loader.data.curr_player;
			MAX_X = int(loader.data.maxX);
			MAX_Y = int(loader.data.maxY);
			autor_login = loader.data.login;
			guest_login = loader.data.guest;
			
			//создаем массив, хранящий цвета точек
			dots = new Array(MAX_X);
			for (var i:int = 0; i < MAX_X; i++)
			{
				dots[i] = new Array(MAX_Y);
				for (var j:int = 0; j < MAX_Y; j++)
					dots[i][j] = int(loader.data.field.substr(i + j * MAX_X, 1)); 
			}
			
			draw();
			
			timer = new Timer(3000); //создаем таймер
			timer.start();
			
			if (PLAYER_COLOR == current_player)
				addEventListener(MouseEvent.CLICK, click);
			else
			{
				timer.addEventListener(TimerEvent.TIMER, tick);
			}
		}
		
		private function init_panel():void
		{
			tf_login_active = new TextFormat();
			tf_login_active.size = 22;
			tf_login_active.bold = true;
			tf_login_active.underline = true;
			
			tf_login_passive = new TextFormat();
			tf_login_passive.size = 22;
			tf_login_passive.bold = false;
			tf_login_passive.underline = false;
			
			/*var tf_header:TextFormat = new TextFormat();
			tf_header.size = 20;
			tf_header.bold = true;*/
			
			tf_info = new TextFormat();
			tf_info.size = 10;
			
			tf_chat = new TextFormat();
			tf_info.size = 18;
			
			tx_login1 = new TextField();
			tx_login1.text = autor_login;
			tx_login1.textColor = 0xFF0000;
			tx_login1.x = 5;
			tx_login1.y = 5;
			tx_login1.height = 40;
			panel.addChild(tx_login1);
			
			tx_login2 = new TextField();
			tx_login2.text = guest_login;
			tx_login2.textColor = 0x0000FF;
			tx_login2.x = 5;
			tx_login2.y = 85;
			tx_login2.height = 40;
			panel.addChild(tx_login2);
			
			tx_dots1 = new TextField();
			tx_dots1.textColor = 0xFF0000;
			tx_dots1.setTextFormat(tf_info);
			tx_dots1.x = 5;
			tx_dots1.y = 45;
			tx_dots1.height = 40;
			panel.addChild(tx_dots1);
			
			tx_dots2 = new TextField();
			tx_dots2.textColor = 0x0000FF;
			tx_dots2.setTextFormat(tf_info);
			tx_dots2.x = 5;
			tx_dots2.y = 125;
			tx_dots2.height = 40;
			panel.addChild(tx_dots2);
			
			
			s1 = new Sprite();
			s1.graphics.beginFill(0xDD3399);
			s1.graphics.drawRect(15, 168, 90, 25);
			s1.graphics.endFill();
			/*loose = new SimpleButton();
			loose.name = "loose";
			loose.x = 15;
			loose.y = 165;
			loose.height = 30;
			loose.width = 90;
			loose.opaqueBackground = 0xFFFFFF;
			loose.addEventListener(MouseEvent.CLICK, looser);
			panel.addChild(loose);*/
			s1.addEventListener(MouseEvent.CLICK, looser);
			panel.addChild(s1);
			
			tx_chat = new TextField();
			tx_chat.multiline = true;
			//tx_chat.scrollV = true;
			tx_chat.text = "";
			tx_chat.x = 5;
			tx_chat.y = 200;
			tx_chat.height = 300;
			tx_chat.width = 110;
			tx_chat.border = true;
			tx_chat.backgroundColor = 0xFFDDEE;
			panel.addChild(tx_chat);
			
			tx_message = new TextField();
			tx_message.text = "";
			tx_message.x = 5;
			tx_message.y = 500;
			tx_message.height = 22;
			tx_message.width = 110;
			tx_message.border = true;
			tx_message.background = true;//?
			tx_message.type = "input";
			panel.addChild(tx_message);
			
			submit_message = new SimpleButton();
			submit_message.name = "submit_message";
			submit_message.x = 15;
			submit_message.y = 522;
			//submit_message.height = 30;
			//submit_message.width = 90;
			//submit_message.label = "dfbdb";
			//submit_message.setSize(30, 90);
			submit_message.addEventListener(MouseEvent.CLICK, submit_mess);
			panel.addChild(submit_message);
			
			s2 = new Sprite();
			s2.graphics.beginFill(0xDD3399);
			s2.graphics.drawRect(15, 525, 90, 25);
			s2.graphics.endFill();
			s2.addEventListener(MouseEvent.CLICK, submit_mess);
			panel.addChild(s2);
		}
		
		private function draw():void
		{
			this.x = 0;
			this.y = 0;
			//привязываем спрайт
			spr.x = PANEL_WIDTH;
			spr.y = 0;
			addChild(spr);
			
			panel.x = 0;
			panel.y = 0;
			addChild(panel);
			
			var pbg:Shape = new Shape();
			pbg.graphics.beginFill(BG_PANEL);
			pbg.graphics.drawRect(0, 0, PANEL_WIDTH, HEIGHT);
			pbg.graphics.endFill();
			panel.addChild(pbg);
			
			init_panel();
			refresh_panel();
			
			//рисуем фон
			var bg:Shape = new Shape();
			bg.graphics.beginFill(BG_COLOR);
			bg.graphics.drawRect(0, 0, WIDTH, HEIGHT);
			bg.graphics.endFill();
			spr.addChild(bg);
			
			//рисуем сетку
			var ln:Shape = new Shape();
			ln.graphics.lineStyle(net_style, NET_COLOR);
			for (var i:int = 0; i < MAX_Y; i++)
			{
				ln.graphics.moveTo(0, h + d * i);
				ln.graphics.lineTo(WIDTH, h + d * i);
				
			}
			for (var j:int = 0; j < MAX_X; j++)
			{
				ln.graphics.moveTo(h + d * j, 0);
				ln.graphics.lineTo(h + d * j, HEIGHT);
			}
			spr.addChild(ln);
			
			var sh:Shape = new Shape();
			for (var i:int = 0; i < MAX_X; i++)
				for (var j:int = 0; j < MAX_Y; j++)
					draw_dot(sh, i * d + h, j * d + h, dots[i][j]);
			
			spr.addChild(sh);
		}
		
		private function click(e:MouseEvent):void
		{
			//проверим, не закончена ли битва
			if (this.winner)
				return;
			
			var offx:int = (e.stageX - h - PANEL_WIDTH) % d; //сдвиг от узла слева
			var offy:int = (e.stageY - h) % d;
			nx = (e.stageX - h - PANEL_WIDTH) / d; //и от какого узла
			ny = (e.stageY - h) / d;
			
			//если близки к узлу, корректируем
			if (offx > d - E)
				nx++;
			else if (offx > E)
				return;
			
			if (offy > d - E)
				ny++;
			else if (offy > E)
				return;
			
			//проверим, принадлежит ли точка полю
			if (nx >= MAX_X || nx < 0 || ny >= MAX_Y || ny < 0)
				return;
			
			//is free?
			if (this.dots[nx][ny] != 0)
				return;
			
			//не ожидаем щелчков
			removeEventListener(MouseEvent.CLICK, click);
			
			//oтправляем ход серверу
			var req:URLRequest = new URLRequest("scripts/new_turn_flash.php");
			req.data = new URLVariables("n=0&x=" + nx + "&y=" + ny);
			var loadvars:URLLoader = new URLLoader();
			loadvars.dataFormat = URLLoaderDataFormat.VARIABLES;
			loadvars.addEventListener(Event.COMPLETE, click_resp);
			
			try
			{
				//MonsterDebugger.trace(this,"clicks to server");
				loadvars.load(req);
			}
			catch (error:Error)
			{
				addEventListener(MouseEvent.CLICK, click);
			}
		}
		
		private function click_resp(e:Event):void
		{
			//MonsterDebugger.trace(this,"server responce");
			var loader:URLLoader = URLLoader(e.target);
			if (loader.data.resp != 'ok')
			{
				//trace('oups!');
				addEventListener(MouseEvent.CLICK, click);
			}
			else
			{
				turn(nx, ny);
				
				refresh_panel();
				
				//MonsterDebugger.trace(this, "turn is complete");
				
				var loadvars:URLLoader = new URLLoader();
				loadvars.dataFormat = URLLoaderDataFormat.VARIABLES;
				loadvars.addEventListener(Event.COMPLETE, refresh);
				try
				{
					timer.addEventListener(TimerEvent.TIMER, tick);
				}
				catch (error:Error)
				{
					trace('FATAL ERROR !!!');
				}
			}
		}
		
		private function refresh(e:Event = null):void
		{
			var loader:URLLoader = URLLoader(e.target);
			if (loader.data.resp != 'yes')
			{
				timer.addEventListener(TimerEvent.TIMER, tick);
				return;
			}
			
			turn(loader.data.x, loader.data.y);
			
			refresh_panel();
				
			addEventListener(MouseEvent.CLICK, click);
		}
		
		private function tick(e:TimerEvent):void
		{
			timer.removeEventListener(TimerEvent.TIMER, tick);
			
			var loadvars:URLLoader = new URLLoader();
			loadvars.dataFormat = URLLoaderDataFormat.VARIABLES;
			loadvars.addEventListener(Event.COMPLETE, refresh);
			try
			{
				loadvars.load(new URLRequest("scripts/refresh_flash.php"));
			}
			catch (error:Error)
			{
				trace('FATAL ERROR !!!');
			}
		}
		
		private function turn(nx:int, ny:int):void
		{
			//отмечаем точку в массиве
			this.dots[nx][ny] = this.current_player;
			
			var newDot:Shape = new Shape();
			draw_dot(newDot, h + nx * d, h + ny * d, current_player);
			
			//try to ocupy
			
			//neighnborns of dot
			var heads:Array = [];
			
			if (nx > 0)
				if (this.dots[nx - 1][ny] != this.current_player)
					heads.push([nx - 1, ny]);
			
			if (nx < MAX_X - 1)
				if (this.dots[nx + 1][ny] != this.current_player)
					heads.push([nx + 1, ny]);
			
			if (ny > 0)
				if (this.dots[nx][ny - 1] != this.current_player)
					heads.push([nx, ny - 1]);
			
			if (ny < MAX_Y - 1)
				if (this.dots[nx][ny + 1] != this.current_player)
					heads.push([nx, ny + 1]);
			
			//MonsterDebugger.trace(this, "start cicle");
			for (var k:int = 0; k < heads.length; k++)
			{
				if (dots[heads[k][0]][heads[k][1]] == this.current_player)
					continue;
				
				var area:Array = [heads[k]];
				var ocupy:Boolean = true;
				
				for (var i:int = 0; i < area.length; i++)
				{
					var xx:int = area[i][0];
					var yy:int = area[i][1];
					var x1:Boolean = (xx <= 0);
					var x0:Boolean = (xx >= MAX_X - 1);
					var y1:Boolean = (yy <= 0);
					var y0:Boolean = (yy >= MAX_Y - 1);
					
					if (xx > 0)
						if (dots[xx - 1][yy] == current_player || dots[xx - 1][yy] == current_player+2 || dots[xx - 1][yy] == current_player+4)
							x1 = true;
					
					if (xx < MAX_X - 1)
						if (dots[xx + 1][yy] == current_player || dots[xx + 1][yy] == current_player+2 || dots[xx + 1][yy] == current_player+4)
							x0 = true;
					
					if (yy > 0)
						if (dots[xx][yy - 1] == current_player || dots[xx][yy - 1] == current_player+2 || dots[xx][yy - 1] == current_player+4)
							y1 = true;
					
					if (yy < MAX_Y - 1)
						if (dots[xx][yy + 1] == current_player || dots[xx][yy + 1] == current_player+2 || dots[xx][yy + 1] == current_player+4)
							y0 = true;
					
					for each (var v:Array in area)
						if (v[1] == yy)
						{
							if (v[0] == xx - 1)
								x1 = true;
							else if (v[0] == xx + 1)
								x0 = true;
						}
						else if (v[0] == xx)
						{
							if (v[1] == yy - 1)
								y1 = true;
							else if (v[1] == yy + 1)
								y0 = true;
						}
					
					if (!x1)
						area.push([xx - 1, yy])
					if (!x0)
						area.push([xx + 1, yy])
					if (!y1)
						area.push([xx, yy - 1])
					if (!y0)
						area.push([xx, yy + 1])
					
					if (area.length > max_area)
					{
						ocupy = false;
						break;
					}
				}
				
				if (ocupy)
				{
					var newx:int, newy:int;
					for (var j:int = 0; j < area.length; j++)
					{
						newx = area[j][0];
						newy = area[j][1];
						
						if (dots[newx][newy] == 0)
							dots[newx][newy] = current_player + 2;
						else
							dots[newx][newy] = current_player + 4;
						
						draw_dot(newDot, newx * d + h, newy * d + h, dots[newx][newy]);
					}
				}
			}
			//MonsterDebugger.trace(this, "end cicle");

			//check winner
			var num:int = 0;
			for (var i:int = 0; i < MAX_X; i++)
				for (var j:int = 0; j < MAX_Y; j++)
					if (dots[i][j] == current_player || dots[i][j] == current_player+2 || dots[i][j] == current_player+4)
						num++;
			
			if (num >= win_area)
			{
				this.winner = this.current_player;
				var s:String = 'Graduations! Player ' + (this.current_player) + 'WIN!';
				var tf:TextField = new TextField();
				tf.text = s;
				tf.width = 175;
				tf.x = 125;
				tf.y = 150;
				this.spr.addChild(tf);
			}
			
			if (this.current_player == 1)
				this.current_player = 2;
			else 
				this.current_player = 1;
			
			spr.addChild(newDot);
		}
		
		private function draw_dot(s:Shape, x:int, y:int, type:int):void
		{
			switch (type)
			{
				case 1:
					s.graphics.beginFill(COLOR1);
					s.graphics.drawCircle(x, y, dot_rad);
					s.graphics.endFill();
					break;
				case 2:
					s.graphics.beginFill(COLOR2);
					s.graphics.drawCircle(x, y, dot_rad);
					s.graphics.endFill();
					break;
				case 3:
					s.graphics.beginFill(COLOR1);
					s.graphics.drawCircle(x, y, dot_rad/2+1);
					s.graphics.endFill();
					break;
				case 4:
					s.graphics.beginFill(COLOR2);
					s.graphics.drawCircle(x, y, dot_rad/2+1);
					s.graphics.endFill();
					break;
				case 5:
					s.graphics.beginFill(COLOR1);
					s.graphics.drawCircle(x, y, dot_rad);
					s.graphics.endFill();
					s.graphics.beginFill(COLOR2);
					s.graphics.drawCircle(x, y, dot_rad/2);
					s.graphics.endFill();
					break;
				case 6:
					s.graphics.beginFill(COLOR2);
					s.graphics.drawCircle(x, y, dot_rad);
					s.graphics.endFill();
					s.graphics.beginFill(COLOR1);
					s.graphics.drawCircle(x, y, dot_rad/2);
					s.graphics.endFill();
					break;
			}
			
		}
	
		private function refresh_panel():void
		{
			if (current_player == 1)
			{
				tx_login1.setTextFormat(tf_login_active);
				tx_login2.setTextFormat(tf_login_passive);
			}
			else
			{
				tx_login2.setTextFormat(tf_login_active);
				tx_login1.setTextFormat(tf_login_passive);
			}
			tx_dots1.text = String(getSq(1)) + '/' + win_area;
			tx_dots2.text = String(getSq(2)) + '/' + win_area;
			
		}
		
		private function looser(e:Event):void
		{
			var loadvars:URLLoader = new URLLoader();
			try
			{
				loadvars.load(new URLRequest("scripts/loose.php"));
			}
			catch (e:Error)
			{
			
			}
		}
		
		private function submit_mess(e:Event):void
		{
			
		}
	}

}